package com.xq.tmall.agu.ferign;

import com.alibaba.excel.util.DateUtils;
import com.xq.tmall.agu.job.ITimerJob;
import com.xq.tmall.entity.StockSector;
import com.xq.tmall.entity.WebPage;
import com.xq.tmall.service.StockSectorService;
import com.xq.tmall.service.TaskQueueService;
import com.xq.tmall.util.ITimeJobFactory;
import com.xq.tmall.util.IpFerginUtil;
import com.xq.tmall.util.JsoupUitl;
import com.xq.tmall.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.ehcache.core.internal.util.CollectionUtil;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.*;

@Slf4j
@Component("StockSectorSpider")
public class StockSectorSpider implements Runnable {

    private String url = "https://push2.eastmoney.com/api/qt/clist/get";

    private static final int MAX_RETRIES = 3;

    private static final long BASE_DELAY_MS = 5000;

    @Resource
    private StockSectorService stockSectorService;

    @Resource
    private TaskQueueService taskQueueService;

    public boolean processPageWithRetry(int page) {
        int attempt = 0;
        while (attempt < MAX_RETRIES) {
            try {
                IpFerginUtil ipFerginUtil = SpringContextUtil.getBean(IpFerginUtil.class);
                Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(ipFerginUtil.getRedisIp(), Integer.parseInt(ipFerginUtil.getRedisPort())));
                log.info("stockSectorSpider====proxy,ip:{},port:{}", ipFerginUtil.getRedisIp(), ipFerginUtil.getRedisPort());
                if (proxy == null) {
                    log.info("未设置代理请检查!");
                    throw new Exception("未设置代理请检查");
                }
                Map<String, String> params = new HashMap<>();
                params.put("np", "1");
                params.put("fltt", "1");
                params.put("invt", "2");
                params.put("cb", "jQuery37108403873058354381_" + new Date().getTime());
                params.put("fs", "m:90+t:3+f:!50");
                params.put("fields", "f12,f13,f14,f1,f2,f4,f3,f152,f20,f8,f104,f105,f128,f140,f141,f207,f208,f209,f136,f222");
                params.put("fid", "f3");
                params.put("pz", "20");
                params.put("po", "1");
                params.put("dect", "1");
                params.put("ut", "fa5fd1943c7b386f172d6893dbfba10b");
                params.put("wbp2u", "4519325966461096|0|1|0|web_" + new Date().getTime());
                params.put("pn", String.valueOf(page));
                WebPage webPage = JsoupUitl.getWebPage(url, Connection.Method.GET,
                        8000, ipFerginUtil.getUseAgent(), "https://quote.eastmoney.com/", null, proxy, true, null, params);
                log.info("调用StockSectorSpider==webPage:" + webPage);
                String bodyText = webPage.getDocument().body().text();
                String json = extractJsonp(bodyText);
                savePageData(page, json);
                return true;
            } catch (Exception e) {
                attempt++;
                log.info("第"+page+"页"+attempt+"次尝试失败:"+ e.getMessage());

                if (attempt < MAX_RETRIES) {
                    try {
                        // 指数退避延迟
                        long delay = (long) (BASE_DELAY_MS * Math.pow(2, attempt));
                        Thread.sleep(delay);
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        return false;
                    }
                }
            }
        }
        return false;
    }


    private static String extractJsonp(String html) {
        Document doc = Jsoup.parse(html);
        String bodyText = doc.body().text();

        int start = bodyText.indexOf("{");
        int end = bodyText.lastIndexOf("}");

        if (start == -1 || end == -1) {
            throw new IllegalArgumentException("Invalid JSONP format");
        }

        return bodyText.substring(start, end + 1);
    }

    public void savePageData(int page, String json) {
        stockSectorService.batchUpdate(json);
        log.info("成功保存第"+page+"页数据");
    }

    @Override
    public void run() {
        log.info("开始执行板块更新========");
        // 判断板块是否已更新
        Map<String, Object> params = new HashMap<>();
        params.put("historyDate", DateUtils.format(new Date(), "yyyy-MM-dd"));
        List<StockSector> sectorList = stockSectorService.findAllStockSectorInfo(params);
        if(CollectionUtils.isNotEmpty(sectorList)){
            return;
        }
        taskQueueService.initializeTasks(22);
        while (true) {
            Integer page = taskQueueService.getNextTask();
            if (page == null) {
                break; // 所有任务已完成
            }
            boolean success = processPageWithRetry(page);

            if (success) {
                taskQueueService.markTaskCompleted(page);
            } else {
                taskQueueService.markTaskFailed(page);
            }
            // 添加延迟以避免请求过于频繁
            try {
                Thread.sleep(60000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                break;
            }
        }
        // 检查是否有失败任务
        if (taskQueueService.getFailedCount() > 0) {
            log.info("有失败任务，可以调用taskQueueService.retryFailedTasks()重试");
            taskQueueService.retryFailedTasks();
        }
        try {
            ITimeJobFactory.getJob(ITimeJobFactory.TIMEJOB.HISTORY).execute(ITimerJob.COMMAND.STOP);
        } catch (Exception e) {
            log.info("StockSectorSpider关闭线程异常");
        }
        log.info("结束执行板块更新========");
    }
}
